package utils

import (
	"reflect"
	"sort"
	"unsafe"
)
// 切片类型强制转换
// 为了安全，当两个切片类型[]T和[]Y的底层原始切片类型不同时，Go语言是无法直接转换类型的。
// 不过安全都是有一定代价的，有时候这种转换是有它的价值的——可以简化编码或者是提升代码的性能。
// 比如在64位系统上，需要对一个[]float64切片进行高速排序，我们可以将它强制转为[]int整数切片，
// 然后以整数的方式进行排序（因为float64遵循IEEE754浮点数标准特性，当浮点数有序时对应的整数也必然是有序的）。

// 下面的代码通过两种方法将[]float64类型的切片转换为[]int类型的切片：
// 版本 1
func SortFloat64FastV1(a []float64) {
	// 强制类型转换
	var b []int = ((*[1 << 20]int)(unsafe.Pointer(&a[0]))[:len(a):cap(a)])
	// 以int方式给 float64 排序
	sort.Ints(b)
}
// 版本 2
func SortFloat64FastV2(a []float64) {
	// 通过 reflect.SliceHeader 更新切片头部信息实现转换
	var c []int
	aHdr := (*reflect.SliceHeader)(unsafe.Pointer(&a))
	cHdr := (*reflect.SliceHeader)(unsafe.Pointer(&c))
	*cHdr = *aHdr
	// 以int方式给 float64 排序
	sort.Ints(c)
}